/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package knn;
import java.io.IOException;
import java.util.ArrayList;
import java.util.TreeMap;
import java.util.Map;

import id3.InputFile;
import id3.Record;
import id3.Attribute;
import id3.AttributeDetail;
import id3.Utility;


/**
 *
 * @author Lenovo
 */
public class KNN {
    private ArrayList<Record> records;
    private ArrayList<Record> testrecords;
    private ArrayList<String> hasilInferensi;

    public KNN ()
    {
        records = new ArrayList<Record>();
        testrecords = new ArrayList<Record>();
    }

    public KNN (String file_records, String file_test_records)
    {
        try
        {
            records = InputFile.buildRecords(file_records);
            testrecords = InputFile.buildRecordTest(file_test_records);
        }
        catch (IOException e)
        {
            System.out.println("error : "+e.getMessage());
        }
    }

    public KNN (ArrayList<Record> data, ArrayList<Record> data_test)
    {
        records = data;
        testrecords = data_test;
    }

    public void classify ()
    {
        int n_kol=records.get(0).attributes.size()-1, N=records.size();
        int i, j, k, l, dist;
        double weight, max;
        String val, result;
        TreeMap<String, Double> temp;
        ArrayList<Attribute> record;
        ArrayList<AttributeDetail> attr = Utility.attributeDetails;
        ArrayList<TreeMap<String, Integer>> des = new ArrayList<TreeMap<String, Integer>>();
        Integer[] nilai = new Integer[n_kol];
        hasilInferensi = new ArrayList<String>();
        
        for (i=0; i<attr.size(); ++i)
        {
            TreeMap<String, Integer> tm = new TreeMap<String, Integer>();
            for (j=0; j<attr.get(i).list_value.size(); ++j)
                tm.put(attr.get(i).list_value.get(j), j);
            des.add(tm);
        }

        for (i=0; i<testrecords.size(); ++i)
        {
            record = testrecords.get(i).attributes;
            temp = new TreeMap<String, Double>();
            for (j=0; j<n_kol; ++j)
                nilai[j] = des.get(j).get(record.get(j).value);
            for (j=0; j<N; ++j)
            {
                record = records.get(j).attributes;
                dist=0;
                for (k=0; k<n_kol; ++k)
                {
                    l = nilai[k] - des.get(k).get(record.get(k).value);
                    dist += l*l;
                }
                if (dist == 0)
                    weight = N;
                else
                    weight = 1.0/dist;
                val = records.get(j).attributes.get(n_kol).value;
                if (temp.get(val)==null)
                    temp.put(val, weight);
                else
                    temp.put(val, temp.get(val)+weight);
            }
            
            max = -1.0;
            result = "No data, no result...";
            for (Map.Entry<String, Double> entry : temp.entrySet())
                if (entry.getValue() > max)
                {
                    result = entry.getKey();
                    max = entry.getValue();
                }
            hasilInferensi.add(result);
        }
    }

    public ArrayList<String> get_hasil_inferensi()
    {
        return hasilInferensi;
    }
}
